home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / CONTRIB / lineblend.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.7 KB  |  258 lines

  1.  
  2. /* lineblend.c
  3.  * 
  4.  * To compile: cc -o lineblend lineblend.c -lGL -lGLU -lX11 -lglut -lXmu
  5.  *
  6.  * Usage: lineblend
  7.  *
  8.  * This is an puffed up version of the first GL assignment we had for my
  9.  * graphics class: write a 2-d openGL program w/ color and interactivity.
  10.  *
  11.  * Left and middle buttons drawn colored lines, right button brings up a menu
  12.  * with a few options.  If you draw for long enough and then hit pick
  13.  * "redraw" (or resize or uncover the window) it takes so long to redraw
  14.  * all the lines it is kind of like a kaleidoscope animation. Or something.
  15.  *
  16.  * Philip Winston - 2/11/95  (modified: 2/12)
  17.  * pwinston@hmc.edu
  18.  * http://www.cs.hmc.edu/people/pwinston
  19.  *        
  20.  */
  21.  
  22. #include <GL/glut.h>
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26.  
  27. #ifdef _WIN32
  28. #define drand48() (((float) rand())/((float) RAND_MAX))
  29. #endif
  30.  
  31. typedef enum {MENU_ALPHA_1, MENU_ALPHA_2,  MENU_ALPHA_3, MENU_ALPHA_4,
  32.               MENU_COLOR_1, MENU_COLOR_2,  MENU_COLOR_3, MENU_COLOR_4,
  33.               MENU_ANTI_ON, MENU_ANTI_OFF,
  34.               MENU_ERASE,   MENU_REDRAW,   MENU_QUIT} MenuChoices;
  35.  
  36. typedef enum {SC1, SC2, SC3, SC4} ColorScheme;
  37.  
  38. int wwidth, wheight, downbtn = -1, downx, downy;
  39.  
  40. GLuint DispLists = 1;
  41.  
  42. GLfloat Alpha = 0.2;
  43. int Color = SC1;
  44.  
  45. void myglInit(void)
  46. {
  47.   glLineWidth(10.0);
  48.   glEnable(GL_BLEND);
  49.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  50.  
  51.   glMatrixMode(GL_PROJECTION);
  52.   glLoadIdentity();
  53.   gluOrtho2D(-0.5,0.5,-0.5,0.5);
  54.  
  55.   glMatrixMode(GL_MODELVIEW);
  56.   glLoadIdentity();
  57.  
  58.   glFlush();
  59.  
  60. void myreshape(GLsizei w, GLsizei h)
  61. {
  62.   wwidth = w; wheight = h;
  63.   glViewport(0,0,w,h);
  64.   glClear(GL_COLOR_BUFFER_BIT);
  65.   glFlush();
  66. }
  67.  
  68. void mydisplay(void)
  69. {
  70.   GLuint i;
  71.  
  72.   glClear(GL_COLOR_BUFFER_BIT);
  73.  
  74.   for (i = 0; i < DispLists; i++)
  75.     glCallList(i);
  76.  
  77.   glFlush();
  78. }
  79.  
  80. void drawline(int x, int y)
  81. {
  82.   GLfloat fx =   (float)(x - downx)/wwidth,
  83.           fy = -((float)(y - downy)/wheight),
  84.           r1, g1, b1, r2, g2, b2;
  85.  
  86.   switch(Color) {      /* four different ways to pick colors */
  87.     case SC1:          /* just kind of random formulas...    */
  88.       r1 = fy+1; g1 = 0;    b1 = (float)x/wwidth;
  89.       r2 = 0;    g2 = fy+1; b2 = 1-(float)x/wwidth;
  90.       break;
  91.     case SC2:
  92.       r1 = fx+fy+1; g1 = 0;       b1 = 0;
  93.       r2 = 0;       g2 = fx+fy+1; b2 = 0;
  94.       break;
  95.     case SC3:
  96.       r1 = 0;   g1 = (float)downx/wwidth; b1 = (float)x/wwidth;
  97.       r2 = 0;   g2 = (float)y/wheight; b2 = (float)downy/wheight;
  98.       break;
  99.     case SC4:
  100.       r1 = drand48(); g1 = drand48(); b1 = (float)downx/(wwidth*1.5);
  101.       r2 = drand48(); g2 = (float)downy/(wheight*1.5); b2 = drand48();
  102.       break;
  103.   }
  104.  
  105.  
  106.   glBegin(GL_LINES);
  107.         glColor4f(r1, g1, b1, Alpha);
  108.     switch(downbtn) {
  109.       case GLUT_LEFT_BUTTON:   glVertex2f(0,0);     break;        
  110.       case GLUT_MIDDLE_BUTTON: glVertex2f(-fx,-fy); break;
  111.       }
  112.     glColor4f(r2, g2, b2, Alpha); glVertex2f(fx,fy);
  113.   glEnd();
  114.  
  115.   glFlush();
  116. }
  117.  
  118. void mousebutton(int btn, int state, int x, int y)
  119. {
  120.   GLfloat fx =  (float)x/wwidth - 0.5,
  121.           fy = -(float)y/wheight + 0.5;
  122.  
  123.   if (state == GLUT_DOWN && downbtn == -1) {
  124.     glNewList(DispLists++, GL_COMPILE_AND_EXECUTE);
  125.     glPushMatrix();
  126.     glTranslatef(fx, fy, 0);
  127.     downbtn = btn;
  128.     downx = x;
  129.     downy = y;
  130.     drawline(x, y);
  131.   } else if (state == GLUT_UP && btn == downbtn) {
  132.     glPopMatrix();
  133.     glEndList();
  134.     downbtn = -1;
  135.   }
  136. }
  137.  
  138. /*
  139.  * For some reason I felt like doing these check boxes -- it is kind of
  140.  * lame the way I did it, though.  Probably a smarter and easier way.
  141.  */
  142.  
  143. void handlealphamenu(int value)
  144. {
  145.   glutChangeToMenuEntry(1,"[   ] 0.05", MENU_ALPHA_1);  
  146.   glutChangeToMenuEntry(2,"[   ] 0.20", MENU_ALPHA_2);
  147.   glutChangeToMenuEntry(3,"[   ] 0.50", MENU_ALPHA_3);
  148.   glutChangeToMenuEntry(4,"[   ] 1.00", MENU_ALPHA_4);
  149.   switch (value) {
  150.     case MENU_ALPHA_1:
  151.       glutChangeToMenuEntry(1, "[ * ] 0.05", MENU_ALPHA_1);  
  152.       Alpha = 0.05; break;
  153.     case MENU_ALPHA_2:
  154.       glutChangeToMenuEntry(2, "[ * ] 0.20", MENU_ALPHA_2);
  155.       Alpha = 0.2; break;
  156.     case MENU_ALPHA_3:
  157.       glutChangeToMenuEntry(3, "[ * ] 0.50", MENU_ALPHA_3);
  158.       Alpha = 0.5; break;
  159.     case MENU_ALPHA_4:
  160.       glutChangeToMenuEntry(4, "[ * ] 1.00", MENU_ALPHA_4);
  161.       Alpha = 1.0; break;
  162.     }
  163. }
  164.  
  165. void handlecolormenu(int value)
  166. {
  167.   glutChangeToMenuEntry(1,"[   ] Various", MENU_COLOR_1);  
  168.   glutChangeToMenuEntry(2,"[   ] Red/Green  ", MENU_COLOR_2);
  169.   glutChangeToMenuEntry(3,"[   ] Blue/Green", MENU_COLOR_3);
  170.   glutChangeToMenuEntry(4,"[   ] Random", MENU_COLOR_4);
  171.   switch (value) {
  172.     case MENU_COLOR_1:
  173.       glutChangeToMenuEntry(1, "[ * ] Various", MENU_COLOR_1);  
  174.       Color = SC1; break;
  175.     case MENU_COLOR_2:
  176.       glutChangeToMenuEntry(2, "[ * ] Red/Green", MENU_COLOR_2);
  177.       Color = SC2; break;
  178.     case MENU_COLOR_3:
  179.       glutChangeToMenuEntry(3, "[ * ] Blue/Green", MENU_COLOR_3);
  180.       Color = SC3; break;
  181.     case MENU_COLOR_4:
  182.       glutChangeToMenuEntry(4, "[ * ] Random", MENU_COLOR_4);
  183.       Color = SC4; break;
  184.     }
  185. }
  186.  
  187. void handlemenu(int value)
  188. {
  189.   switch (value) {
  190.     case MENU_ANTI_OFF:
  191.       glDisable(GL_LINE_SMOOTH);
  192.       glutChangeToMenuEntry(3, "anti-aliasing [NO]", MENU_ANTI_ON);
  193.       break;
  194.     case MENU_ANTI_ON:
  195.       glEnable(GL_LINE_SMOOTH);
  196.       glutChangeToMenuEntry(3, "anti-aliasing [YES]", MENU_ANTI_OFF);
  197.       break;
  198.     case MENU_REDRAW:
  199.       glutPostRedisplay();
  200.       break;
  201.     case MENU_ERASE:
  202.       glDeleteLists(0, DispLists);
  203.       DispLists = 1;
  204.       mydisplay();
  205.       break;
  206.     case MENU_QUIT:
  207.       exit(0);
  208.       break;
  209.     }
  210. }
  211.  
  212. void myMenuInit(void)
  213. {
  214.   int sub1,sub2,sub3;
  215.  
  216.   sub3 = glutCreateMenu(handlealphamenu);
  217.   glutAddMenuEntry("[   ] 0.05", MENU_ALPHA_1);  
  218.   glutAddMenuEntry("[ * ] 0.20", MENU_ALPHA_2);
  219.   glutAddMenuEntry("[   ] 0.50", MENU_ALPHA_3);
  220.   glutAddMenuEntry("[   ] 1.00", MENU_ALPHA_4);
  221.   sub2 = glutCreateMenu(handlecolormenu);
  222.   glutAddMenuEntry("[ * ] Various", MENU_COLOR_1);  
  223.   glutAddMenuEntry("[   ] Red/Green", MENU_COLOR_2);
  224.   glutAddMenuEntry("[   ] Blue/Green", MENU_COLOR_3);
  225.   glutAddMenuEntry("[   ] Random", MENU_COLOR_4);
  226.   sub1 = glutCreateMenu(handlemenu);
  227.   glutAddSubMenu("Colors", sub2);
  228.   glutAddSubMenu("Alpha", sub3);
  229.   glutAddMenuEntry("anti-aliasing [NO]", MENU_ANTI_ON);
  230.   glutCreateMenu(handlemenu);
  231.   glutAddSubMenu("Lines", sub1);
  232.   glutAddMenuEntry("Erase", MENU_ERASE);
  233.   glutAddMenuEntry("Redraw", MENU_REDRAW);
  234.   glutAddMenuEntry("Quit", MENU_QUIT);
  235.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  236. }
  237.  
  238. int main(int argc, char** argv)
  239. {
  240.   glutInit(&argc, argv);
  241.   glutInitWindowSize(512, 512);
  242.   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  243.   glutCreateWindow("lineblend");
  244.  
  245.   myglInit(); 
  246.   myMenuInit();
  247.  
  248.   glutReshapeFunc(myreshape);
  249.   glutMouseFunc(mousebutton);
  250.   glutMotionFunc(drawline);
  251.   glutDisplayFunc(mydisplay);
  252.  
  253.   glutMainLoop();
  254.   return 0;             /* ANSI C requires main to return int. */
  255. }
  256.  
  257.